package org.pyq.core;

import org.pyq.core.process.Process;
import org.pyq.core.process.SqlProcess;

import java.lang.instrument.ClassDefinition;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author pengYongQiang
 * @date 2022/1/7 17:41
 */
public class Main {
    private Instrumentation inst;

    public synchronized static void getInstance(Instrumentation instrumentation, String args) {
        new Main(instrumentation, args);
    }

    public Main(Instrumentation instrumentation, String args) {
        this.inst = instrumentation;

        ManagerFactory managerFactory = createManagerFactory();

        registerProcess(managerFactory);

        invokeProcess(managerFactory, args);

    }

    private void invokeProcess(ManagerFactory managerFactory, String args) {
        List<Process> processes = managerFactory.getProcesses();

        String arg1 = args;

        if (arg1==null|| "".equals(arg1.trim())){
            arg1 = ".*";
        }

        if ("reset".equals(arg1)) {
            for (Process process : processes) {
                byte[] back = process.reset();
                if (back == null) {
                    continue;
                }
                ClassDefinition classDefinition = new ClassDefinition(process.getClazz(), back);
                try {
                    inst.redefineClasses(classDefinition);
                } catch (ClassNotFoundException | UnmodifiableClassException e) {
                    e.printStackTrace();
                }
            }
        } else {
            System.out.println("正则匹配:"+arg1);

            for (Process process : processes) {
                byte[] invoke = process.invoke(arg1);
                if (invoke == null) {
                    continue;
                }
                ClassDefinition classDefinition = new ClassDefinition(process.getClazz(), invoke);
                try {
                    inst.redefineClasses(classDefinition);
                } catch (ClassNotFoundException | UnmodifiableClassException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void registerProcess(ManagerFactory managerFactory) {
        //managerFactory.addProcesses(new TestProcess(inst));
        managerFactory.addProcesses(new SqlProcess(inst));

        for (Process process : managerFactory.getProcesses()) {
            process.init();
        }
    }

    private ManagerFactory createManagerFactory() {
        return new ManagerFactory(inst);
    }


}
